﻿using System;
using Cysharp.Threading.Tasks;
using GameFramework.Reference;
using GameFramework.Request.Exception;

namespace GameFramework.Request
{
    /// <summary>
    /// 请求实例抽象类
    /// </summary>
    public abstract class ARequest : AReference, IRequest
    {
        public async UniTask<IResponse> Execute(System.Threading.CancellationToken cancellationToken = default)
        {
            if (SerialId == 0)
                throw new RequestShouldBeGetByReferenceServiceException();

            IResponse response;

            try
            {
                response = await OnExecute(cancellationToken);
            }
            catch (System.Exception e)
            {
                Log.Exception(e);
                response = ReferenceService.GetReference<CommonResponse>().SetErrorCode(GameFrameworkErrorCode.RequestCatchException);
            }

            // 执行完请求后回收请求实例
            this.Recycle();

            if (response != null)
                return response;

            // 应答包为空
            response = ReferenceService.GetReference<CommonResponse>().SetErrorCode(GameFrameworkErrorCode.ResponseIsNull);

            return response;
        }

        protected abstract UniTask<IResponse> OnExecute(System.Threading.CancellationToken cancellationToken);
    }
}